package rexsee.core.storage;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import rexsee.core.alarm.RexseeRemoteCommand;
import rexsee.core.browser.Browser;
import rexsee.core.browser.clazz.JavascriptInterface;
import rexsee.core.lang.RexseeLanguage;
import rexsee.core.transportation.RexseeDownload;
import rexsee.core.utilities.Utilities;
import android.content.Context;
import android.net.Uri;
import android.os.Environment;

public class RexseeFile implements JavascriptInterface {

	public static final String INTERFACE_NAME = "File";
	@Override
	public String getInterfaceName() {
		return mBrowser.application.resources.prefix + INTERFACE_NAME;
	}
	@Override
	public JavascriptInterface getInheritInterface(Browser childBrowser) {
		return this;
	}
	@Override
	public JavascriptInterface getNewInterface(Browser childBrowser) {
		return new RexseeFile(childBrowser);
	}

	protected final Browser mBrowser;
	protected final Context mContext;

	public RexseeFile(Browser browser) {
		mBrowser = browser;
		mContext = browser.getContext();
	}
	public RexseeFile(Context context) {
		mBrowser = null;
		mContext = context;
	}

	protected boolean isValidPath(String path) {
		return true;
	}

	public boolean exists(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) return false;
		if (!path.toLowerCase().startsWith("file://")) return false;
		File file = new File(Uri.parse(path).getPath());
		return file.exists();
	}
	public boolean canRead(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) return false;
		if (!path.toLowerCase().startsWith("file://")) return false;
		File file = new File(Uri.parse(path).getPath());
		return file.exists() && file.canRead();
	}
	public boolean canWrite(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) return false;
		if (!path.toLowerCase().startsWith("file://")) return false;
		File file = new File(Uri.parse(path).getPath());
		return file.exists() && file.canWrite();
	}
	public boolean isDirectory(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) return false;
		if (!path.toLowerCase().startsWith("file://")) return false;
		File file = new File(Uri.parse(path).getPath());
		return file.isDirectory();
	}
	public boolean isFile(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) return false;
		if (!path.toLowerCase().startsWith("file://")) return false;
		File file = new File(Uri.parse(path).getPath());
		return file.isFile();
	}
	public boolean isHidden(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) return false;
		if (!path.toLowerCase().startsWith("file://")) return false;
		File file = new File(Uri.parse(path).getPath());
		return file.isHidden();
	}
	public long lastModified(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return 0;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) return 0;
		if (!path.toLowerCase().startsWith("file://")) return 0;
		File file = new File(Uri.parse(path).getPath());
		if (!file.exists()) return 0;
		if (!file.canRead()) return 0;
		return file.lastModified();
	}
	public boolean setLastModified(String path, long time) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) return false;
		if (!path.toLowerCase().startsWith("file://")) return false;
		File file = new File(Uri.parse(path).getPath());
		if (!file.exists()) return false;
		if (!file.canWrite()) return false;
		return file.setLastModified(time);
	}
	public long size(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return 0;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) return 0;
		if (!path.toLowerCase().startsWith("file://")) return 0;
		File file = new File(Uri.parse(path).getPath());
		if (!file.exists()) return 0;
		if (!file.canRead()) return 0;
		if (file.isDirectory()) {
			long l = 0;
			String[] listfile = file.list();
			for (int i = 0; i < listfile.length; i++) {
				File subFile = new File(file.toString() + "/" + listfile[i].toString());
				l += size("file://" + subFile.getAbsolutePath());
			}
			return l + file.length();
		} else {
			return file.length();
		}
	}
	public String dir(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return null;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) return "";
		if (!path.toLowerCase().startsWith("file://")) return "";
		File file = new File(Uri.parse(path).getPath());
		if (!file.exists()) return "";
		if (!file.canRead()) return "";
		if (file.isDirectory()) {
			String[] listfile = file.list();
			String rtn = "";
			for (int i = 0; i < listfile.length; i++) {
				String tmp = "file://" + file.toString() + "/" + listfile[i].toString();
				rtn += (i == 0) ? "\"" + tmp + "\"" : ",\"" + tmp + "\"";
			}
			return "[" + rtn + "]";
		} else {
			return "";
		}
	}
	public String getParent(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return null;
		}
		String parent = (new File(Uri.parse(path).getPath())).getParent();
		return (parent == null) ? "" : "file://" + parent;
	}

	public boolean newFile(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		File file = Utilities.prepareWriteFile(path);
		if (file == null) return false;
		try {
			return file.createNewFile();
		} catch (IOException e) {
			return false;
		}
	}
	public boolean newDir(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) return false;
		if (!path.toLowerCase().startsWith("file://")) return false;
		File file = new File(Uri.parse(path).getPath());
		return file.mkdirs();
	}
	public boolean remove(String path) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		return RexseeRemoteCommand.remove(path);
	}
	public boolean renameTo(String path, String newPath) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		File file = Utilities.prepareReadFile(path);
		File newFile = Utilities.prepareWriteFile(newPath);
		if (file == null || newFile == null) return false;
		return file.renameTo(newFile);
	}
	public boolean copyTo(String path, String newPath) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		return Utilities.copy(path, newPath);
	}
	public String getContent(String path, String encode) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return null;
		}
		byte[] b = Utilities.getContent(path);
		try {
			return (b == null) ? "" : new String(b, encode);
		} catch (UnsupportedEncodingException e) {
			return null;
		}
	}
	public boolean putContent(String path, String content, String encode) {
		if (!isValidPath(path)) {
			mBrowser.exception(getInterfaceName(), "Invalid path.");
			return false;
		}
		if (content == null) return false;
		try {
			return Utilities.putContent(path, content.getBytes(encode));
		} catch (UnsupportedEncodingException e) {
			return false;
		}
	}

	public String getPrivateDir() {
		File dir = mContext.getDir(RexseeDownload.DOWNLOAD_DIRECTORY, Context.MODE_PRIVATE);
		return "file://" + dir.getParentFile().getAbsolutePath();
	}
	public void tryToCleanPrivateDir() {
		RexseeRemoteCommand.tryToCleanPrivateDir(mContext);
		mBrowser.application.askForExitOrRestart(RexseeLanguage.TITLE_ALERT, RexseeLanguage.MESSAGE_RESTART);
	}

}
